package com.base.lib.utils;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.InputType;
import android.util.Base64;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.EditText;

import com.base.lib.base.BaseActivity;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.util.regex.Pattern.compile;


/**
 * 一般工具类
 * Created by harisucici on 2017/6/13.
 */

public class Utils {
    private static Utils utils;
    // 防止双击
    private long lastClickTime;
    private String EMPTY_CODE = "";

    public static synchronized Utils getInstance() {
        if (utils == null) {
            utils = new Utils();
        }
        return utils;
    }

    public String encode(String s) {
        String result = "";
        try {
            result = URLEncoder.encode(s, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }

    // 获取时间
    public String getTime(String format) {
        format = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat formater = new SimpleDateFormat(format);
        return formater.format(new Date());
    }

    //时间戳转日期
    public String timeToDate(String time, String format) {
        try {
            Long aLong = Long.valueOf(time);
            SimpleDateFormat formater = new SimpleDateFormat(format);
            return formater.format(aLong);
        } catch (NumberFormatException ignored) {
            return time;
        }
    }

    public String timeToDate(Long time, String format) {
        SimpleDateFormat formater = new SimpleDateFormat(format);
        return formater.format(time);
    }

    public String[] timeToDate(String time) {
        String[] timeArray = new String[2];
        try {
            Long aLong = Long.valueOf(time);
            SimpleDateFormat formatDay = new SimpleDateFormat("MM-dd");
            SimpleDateFormat formatTime = new SimpleDateFormat("HH:mm");
            timeArray[0] = formatDay.format(aLong);
            timeArray[1] = formatTime.format(aLong);
            return timeArray;
        } catch (NumberFormatException ignored) {
            timeArray[0] = time;
            return timeArray;
        }
    }

    public String dateToTime(String date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
        String time = "";
        try {
            Date d = dateFormat.parse(date);
            time = timeFormat.format(d);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return time;
    }

    // 获得几天之前或者几天之后的日期

    public String getOtherDay(int day) {
        SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar mCalendar = Calendar.getInstance();
        mCalendar.add(Calendar.DATE, day);
        return formater.format(mCalendar.getTime());
    }

    public String getOtherDay(int day, String format) {
        SimpleDateFormat formater = new SimpleDateFormat(format);
        Calendar mCalendar = Calendar.getInstance();
        mCalendar.add(Calendar.DATE, day);
        return formater.format(mCalendar.getTime());
    }

    // 时区
    public String getStampToTime(long stamp) {
        SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
        timeFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
        return timeFormat.format(new Date(stamp));
    }

    /**
     * 格式化时间（输出类似于 刚刚, 4分钟前, 一小时前, 昨天这样的时间）
     *
     * @param time 需要格式化的时间 如"2014-07-14 19:01:45"
     * @return time为null，或者时间格式不匹配，输出空字符""
     */
    public String formatDisplayTime(long time) {
        String display = "";
        int tMin = 60 * 1000;
        int tHour = 60 * tMin;
        int tDay = 24 * tHour;

        if (time != 0) {
            String pattern = "yyyy-MM-dd HH:mm:ss";
            try {
                Date tDate = new SimpleDateFormat(pattern).parse(timeToDate(time, "yyyy-MM-dd HH:mm:ss"));
                Date today = new Date();
                SimpleDateFormat thisYearDf = new SimpleDateFormat("yyyy");
                SimpleDateFormat todayDf = new SimpleDateFormat("yyyy-MM-dd");
                Date thisYear = new Date(thisYearDf.parse(thisYearDf.format(today)).getTime());
                Date yesterday = new Date(todayDf.parse(todayDf.format(today)).getTime());
                Date beforeYes = new Date(yesterday.getTime() - tDay);
                if (tDate != null) {
                    @SuppressWarnings("unused")
                    SimpleDateFormat halfDf = new SimpleDateFormat("MM月dd日");
                    long dTime = today.getTime() - tDate.getTime();
                    if (tDate.before(thisYear)) {
                        display = new SimpleDateFormat("yyyy年MM月dd日").format(tDate);
                    } else {
                        if (dTime < tMin) {
                            display = "刚刚";
                        } else if (dTime < tHour) {
                            display = (int) Math.ceil(dTime / tMin) + "分钟前";
                        } else if (dTime < tDay && tDate.after(yesterday)) {
                            display = (int) Math.ceil(dTime / tHour) + "小时前";
                        } else if (tDate.after(beforeYes) && tDate.before(yesterday)) {
                            display = "昨天 " + new SimpleDateFormat("HH:mm").format(tDate);
                        } else {
                            display = timeToDate(tDate.getTime(), "yyyy-MM-dd HH:mm:ss");
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return display;
    }

    //获取屏幕的宽度px
    public int getScreenWidth( Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();// 创建了一张白纸
        windowManager.getDefaultDisplay().getMetrics(outMetrics);// 给白纸设置宽高
        return outMetrics.widthPixels;
    }

    //获取屏幕的高度px
    public int getScreenHeight( Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();// 创建了一张白纸
        windowManager.getDefaultDisplay().getMetrics(outMetrics);// 给白纸设置宽高
        return outMetrics.heightPixels;
    }

    //将dp转换为与之相等的px
    public int dp2px( Context context, float dipValue) {
        float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    //根据手机的分辨率从 px(像素) 的单位 转成为 dp
    public int px2dip( Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    //将px值转换为sp值，保证文字大小不变
    public int px2sp( Context context, float pxValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (pxValue / fontScale + 0.5f);
    }

    //将sp值转换为px值，保证文字大小不变
    public int sp2px( Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }

    // 获取activity的view
    public View getContentView( Activity context) {
        return ((ViewGroup) context.findViewById(android.R.id.content)).getChildAt(0);
    }

    /**
     * 验证手机号码
     * 现有手机号段:
     * 移动：139  138  137  136  135  134  147  150  151  152  157  158  159  178 182  183  184  187  188
     * 联通：130  131  132  155  156  185  186  145  176
     * 电信：133  153  177  173  180  181  189
     * 虚拟运营商：
     * 170 171
     */
    public boolean checkMobileNumber( String mobileNumber) {
        boolean flag;
        try {
            Pattern regex = compile("^((13[0-9]|15[012356789]|17[013678]|18[0-9]|14[57])[0-9]{8})$");
            Matcher matcher = regex.matcher(mobileNumber);
            flag = matcher.matches();
        } catch (Exception ignored) {
            flag = false;
        }
        return flag;
    }

    /**
     * 开启新的activity并传值
     *
     * @param fromActivity
     * @param toActivity
     */
    public void startActivity( Activity fromActivity, Class<? extends BaseActivity> toActivity) {
        startActivity(fromActivity, toActivity, null);
    }

    public void startActivity( Activity fromActivity, Class<? extends BaseActivity> toActivity, boolean finishThisActivity) {
        startActivity(fromActivity, toActivity, null);
        if (finishThisActivity) {
            fromActivity.finish();
        }
    }

    public void startActivity( Activity fromActivity, Class<? extends BaseActivity> toActivity,
                               Bundle bundle) {
        startActivity(fromActivity, toActivity, bundle, false);
    }

    public void startActivity( Activity fromActivity, Class<? extends BaseActivity> toActivity,
                               Bundle bundle, boolean finishThisActivity) {
        Intent intent = new Intent(fromActivity, toActivity);
        if (null != bundle) {
            bundle.putString(Constant.ACTIVITY_NAME, fromActivity.getClass().getSimpleName());
            intent.putExtras(bundle);
        } else {
            Bundle b = new Bundle();
            b.putString(Constant.ACTIVITY_NAME, fromActivity.getClass().getSimpleName());
            intent.putExtras(b);
        }
        fromActivity.startActivity(intent);
        if (finishThisActivity) {
            fromActivity.finish();
        }
    }

    public void startActivityForResult( Activity fromActivity, Class<? extends BaseActivity> toActivity, int requestCode) {
        startActivityForResult(fromActivity, toActivity, null, requestCode);
    }

    public void startActivityForResult( Activity fromActivity, Class<? extends BaseActivity> toActivity,
                                        Bundle bundle, int requestCode) {
        startActivityForResult(fromActivity, toActivity, bundle, false, requestCode);
    }

    public void startActivityForResult( Activity fromActivity, Class<? extends BaseActivity> toActivity,
                                        Bundle bundle, boolean finishThisActivity, int requestCode) {
        Intent intent = new Intent(fromActivity, toActivity);
        if (null != bundle) {
            bundle.putString(Constant.ACTIVITY_NAME, fromActivity.getClass().getSimpleName());
            intent.putExtras(bundle);
        } else {
            Bundle b = new Bundle();
            b.putString(Constant.ACTIVITY_NAME, fromActivity.getClass().getSimpleName());
            intent.putExtras(b);
        }
        fromActivity.startActivityForResult(intent, requestCode);
        if (finishThisActivity) {
            fromActivity.finish();
        }
    }

    // 从通讯录选择联系人
    
    public String[] getPhoneContacts( Activity activity,  Uri uri) {
        String[] contact = new String[2];
        ContentResolver cr = activity.getContentResolver();
        Cursor cursor = cr.query(uri, null, null, null, null);
        if (cursor != null) {
            cursor.moveToFirst();
            //取得联系人姓名
            int nameFieldColumnIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
            contact[0] = cursor.getString(nameFieldColumnIndex);
            //取得电话号码
            String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
            Cursor phone = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, null, null);
            if (phone != null) {
                phone.moveToFirst();
                contact[1] = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            }
            phone.close();
            cursor.close();
        } else {
            return null;
        }
        return contact;
    }


    //设定edittext是否显示密码内容
    public void setEditTextPasswordType( EditText editText, boolean isHide) {
        editText.setInputType(isHide ?
                InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD :
                InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
    }


    /**
     * 调用拨号界面
     *
     * @param phone 电话号码
     */
    public void callPhone( Context context, String phone) {
        Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phone));
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }


    public String numberFormat(float f, int m) {

        return String.format("%." + m + "f", f);
    }

    //检查null
    public String checkNullEmpty( String string) {
        String s = (string == null || "null".equals(string) || "[]".equals(string) || string.length() == 0) ? "" : string;
        return s;
    }

    public String checkNullUnKnow( String string) {
        String s = (string == null || "null".equals(string) || string.length() == 0) ? "未知" : string;
        return s;
    }

    public int checkNullZero( String string) {
        int n = (string == null || "null".equals(string) || string.length() == 0) ? 0 : Integer.parseInt(string);
        return n;
    }

    // JsonArrayString 转ArrayList
    
    public ArrayList<Map<String, Object>> jsa2list(String s) {
        ArrayList<Map<String, Object>> dataList = new ArrayList<>();
        JSONArray jsonArray;
        try {
            jsonArray = new JSONArray(s);
            for (int i = 0; i < jsonArray.length(); i++) {
                dataList.add(jso2map(jsonArray.get(i).toString()));
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return dataList;
    }

    
    public ArrayList<String> jsa2listString(String s) {
        ArrayList<String> dataList = new ArrayList<>();
        JSONArray jsonArray;
        try {
            jsonArray = new JSONArray(s);
            for (int i = 0; i < jsonArray.length(); i++) {
                dataList.add(jsonArray.get(i).toString());
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return dataList;
    }


    //JsonObjectString转Map
    
    public Map<String, Object> jso2map( String s) {
        JSONObject jsonObjTemp;
        Map<String, Object> map = new HashMap<>(2);
        if (s == null) {
            return null;
        }
        try {
            jsonObjTemp = new JSONObject(s);
            Iterator ite = jsonObjTemp.keys();
            while (ite.hasNext()) {
                String key = ite.next().toString();
                String value = jsonObjTemp.get(key).toString();
                map.put(key, value);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return map;
    }

    
    public String getMapString( Map<String, Object> map, String index) {
        String s = checkNullEmpty((String) map.get(index));
        return checkNullEmpty((String) map.get(index));
    }

    public int getMapInt( Map<String, Object> map, String index) {
        return checkNullZero((String) map.get(index));
    }

    //base64 互转
    public Bitmap base642Bitmap(String s) {
        byte[] bytes = Base64.decode(s, Base64.DEFAULT);
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }

    //base64 互转
    public String bitmap2Base64(String uri) {
        Bitmap bit = BitmapFactory.decodeFile(uri);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //参数100表示不压缩
        bit.compress(Bitmap.CompressFormat.PNG, 50, bos);
        byte[] bytes = bos.toByteArray();
        return Base64.encodeToString(bytes, Base64.DEFAULT);
    }

    /**
     * 提供精确的加法运算。
     *
     * @param v1 被加数
     * @param v2 加数
     * @return 两个参数的和
     */
    public double add(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).doubleValue();
    }

    /**
     * 提供精确的减法运算。
     *
     * @param v1 被减数
     * @param v2 减数
     * @return 两个参数的差
     */
    public double sub(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2).doubleValue();
    }

    public double sub(String v1, String v2) {
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.subtract(b2).doubleValue();
    }

    /**
     * 提供精确的乘法运算。
     *
     * @param v1 被乘数
     * @param v2 乘数
     * @return 两个参数的积
     */
    public double mul(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2).doubleValue();
    }

    /**
     * 提供（相对）精确的除法运算。当发生除不尽的情况时，由scale参数指
     * 定精度，以后的数字四舍五入。
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 表示表示需要精确到小数点以后几位。
     * @return 两个参数的商
     */
    public double div(double v1, double v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public double div(String v1, String v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 提供精确的小数位四舍五入处理。
     *
     * @param v     需要四舍五入的数字
     * @param scale 小数点后保留几位
     * @return 四舍五入后的结果
     */
    public double round(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(Double.toString(v));
        BigDecimal one = new BigDecimal("1");
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public double round(String v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(v);
        BigDecimal one = new BigDecimal("1");
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }
}

